/**
 * redis 使用
 */
const redis = require("redis");
const redisOptions = require("./redisOptions");

const options = {
    host: redisOptions.host,
    port: redisOptions.port,
    password: redisOptions.password,
    detect_buffers: redisOptions.detect_buffers, // 传入buffer 返回也是buffer 否则会转换成String
    retry_strategy: function (options) {
      // 重连机制
      if (options.error && options.error.code === "ECONNREFUSED") {
        // End reconnecting on a specific error and flush all commands with
        // a individual error
        return new Error("The server refused the connection");
      }
      if (options.total_retry_time > 1000 * 60 * 60) {
        // End reconnecting after a specific timeout and flush all commands
        // with a individual error
        return new Error("Retry time exhausted");
      }
      if (options.attempt > 10) {
        // End reconnecting with built in error
        return undefined;
      }
      // reconnect after
      return Math.min(options.attempt * 100, 3000);
    }
}

const client = redis.createClient(options);
client.auth(redisOptions.password);  

// 存储值
const setValue = (key, value) => {
    if (typeof value === 'string') {
        client.set(key, value)
    } else if (typeof value === 'object') {
        for (let item in value) {
            client.hmset(key, item, value[item],redis.print)
        }
    }
}

// 获取string
const getValue = (key) => {
    return new Promise((resolve, reject) => {
        client.get(key, (err, res) => {
            if (err) {
                reject(err)
            }else{
                resolve(res)
            }
        })
    })
}

// 获取hash
/**
 * 
 * @param {*} key   hash key
 * @param {*} pram  指定属性
 * @returns 
 */
const getHValue = (key,pram = null) => {
    return new Promise((resolve, reject) => {
        if(pram == null){
            client.hgetall(key, function (err, value) {
                if (err) {
                    reject(err)
                } else {
                    resolve(value)
                }
            })
        }else{
            client.hget(key, pram,function (err, value) {
                if (err) {
                    reject(err)
                } else {
                    resolve(value)
                }
            })
        }
    })
}

/**
 * 添加
 * @param {*} key 
 * @param {*} value 
 * @param {*} dir 0左 1右
 */
const pushValue = function(key,value,dir){
    return new Promise((resolve, reject) => {
        if(dir == 0){
            client.lpush(key,value);
        }else{
            client.rpush(key,value);
        }
    });
}  

// 移除列表元素
const lremValue = function(key){
    return new Promise((resolve, reject) =>{
        client.lrem(key,0,-1, function(err, data) {
            if (err) {
                reject(err);
                return;
            }
            resolve(data);
        });
    })
}

// 获取列表指定范围内的元素
const lrangeValue = function(key,start,end){
    return new Promise((resolve, reject) => {
        client.lrange(key, start, end, function(err, data) {
            if (err) {
                reject(err);
                return;
            }
            resolve(data);
        });
    });
}

//移除第一个
const lpopValue = function(key){
    return new Promise((resolve, reject) => {
        client.lpop(key,function(err, data) {
            if (err) {
                reject(err);
                return;
            }
            resolve(data);
        });
    });
}


const removeAll = function(key){
    return new Promise((resolve,reject)=>{
        client.LLEN (key,(function(err,data){
            if(err){
                reject(err);
            }else{
                resolve(data);
            }
        // }).then((data)=>{
        //     while(data > 0){
        //         lpopValue(key,(err)=>{
        //             if(err){
        //                 return;
        //             }
        //             removeAll(key);
        //         })
        //     }
        // }).catch((err)=>{
        //     console.log(err);
        }));
    })
}

/**
 * 排行耪的有序集合
 * @param {*} key 
 * @param {*} num 
 * @returns 
 */
const zaddValue = function(key,num){
    return new Promise((resolve, reject) => {
        client.zadd(key,num,function(err, data) {
            if (err) {
                reject(err);
                return;
            }
            resolve(data);
        });
    });
}

const zrangeValue = function(key,start,end){
    return new Promise((resolve, reject) => {
        client.zrange(key,start,end,function(err, data) {
            if (err) {
                reject(err);
                return;
            }
            resolve(data);
        });
    });
}

// 导出
module.exports = {
    setValue,
    getValue,
    pushValue,
    removeAll,
    lremValue,
    lrangeValue,
    lpopValue,
    zaddValue,
    zrangeValue,
    getHValue
} 



client.on("connect",function(err){
    console.log("=======connect======");
});

client.on("ready", function() {
	console.log("========ready=========");
});

client.on("end", function() {
	console.log("========end=========");
});

client.on("reconnecting", function() {
	console.log("========reconnecting=========");
});

client.on("error", function(err) {
	console.log("Redis Client Error ",err);
});

// // end 